<?php

namespace App\Jobs;

use App\Admin\Repositories\Project as RepositoriesProject;
use App\Models\ContractTemplate;
use App\Models\Project;
use App\Models\ProjectAgreement;
use App\Services\TimeService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\Job as JobContract;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use PhpOffice\PhpWord\TemplateProcessor;
use Qiniu\Storage\ResumeUploader;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use zgldh\QiniuStorage\QiniuStorage;

class GenerateAgreementJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 2;

    public $maxExceptions = 2;

    public function retryUntil()
    {
        return now()->addMinutes(5);
    }

    /** @var ProjectAgreement */
    protected $agreement;

    /** @var Project  */
    protected $project;
    protected $user;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Project $project, ProjectAgreement $agreement, $user)
    {
        $this->project = $project;
        $this->agreement = $agreement;
        $this->user = $user;
    }


    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

        try {
            Log::info('----------生成协议调度任务开始了----------' . json_encode($this->project) . ' ====== 协议填充内容 ====== ' . json_encode($this->agreement) . '++++++++++ 用户填充信息 ++++++++++' . json_encode($this->user));
            $tplModel = ContractTemplate::where('id', $this->project->tpl_id)->first();
            $path  = storage_path('app/public/') . $tplModel->url;
            // if ($path = downloadFile($tplModel->url)) {
            if ($path) {
                // $template = new TemplateProcessor(app()->basePath() . DIRECTORY_SEPARATOR . $path);
                $template = new TemplateProcessor($path);
                $datetime = TimeService::formatTimeToString($this->agreement['active_date']);
                
                $beforeAfterTax = RepositoriesProject::getBefoeAfterTax();
                $role = RepositoriesProject::getFeeTypeOptions();
                // todo 套入协议模板数据
                $template->setValues([
                    'user_auth_name' => $this->agreement['user_auth_name'],
                    'active_date' => $datetime,
                    'active_week' => $this->agreement['active_week'],
                    'active_time_begin' => isset($this->agreement['active_time_begin']) && !empty($this->agreement['active_time_begin']) ? $this->agreement['active_time_begin'] : '',
                    // 'active_time_end' => $this->agreement['active_time_end'],
                    'active_time_end' => isset($this->agreement['active_time_begin']) && !empty($this->agreement['active_time_begin']) ? $this->agreement['active_time_begin'] : '',
                    'active_name' => $this->project['active_name'],
                    'role' =>  isset($role[$this->agreement['role']]) ? $role[$this->agreement['role']] : '',
                    'before_after_tax' => isset($beforeAfterTax[$this->agreement['before_after_tax']]) ? $beforeAfterTax[$this->agreement['before_after_tax']] : '',
                    'sponsor' => $this->project['sponsor'],
                    'fee_type_value' => $this->agreement['fee_type_value'],
                    'fee_type_key' => $this->user['fee_type_name'],
                    'company' => $this->project['company'],
                    'company_short' => $this->project['company_short'],
                    'bank_card' => $this->agreement['bank_card'],
                    'bank_addr' => $this->agreement['bank_addr'],
                    'bank_name' => $this->agreement['bank_name'],
                    'id_number' => $this->user['id_number'],
                    'phone' => $this->user['phone'],
                    'unit' => $this->user['unit'],
                    'agreement_code' => $this->agreement['agreement_code'],
                ]);

                $pathinfo = pathinfo($path);
                // $newFile = app()->basePath() . DIRECTORY_SEPARATOR . $pathinfo['dirname'] . DIRECTORY_SEPARATOR . 'new-' . $this->agreement['user_auth_name'] . '-' . $this->agreement['active_date'] . '-' . uniqid() . '-' . $pathinfo['basename'];
                $newFile = $pathinfo['dirname'] . DIRECTORY_SEPARATOR . 'new-' . $this->agreement['user_auth_name'] . '-' . $this->agreement['active_date'] . '-' . uniqid() . '-' . $pathinfo['basename'];

                $template->saveAs($newFile);
                Log::info('-------生成新的协议文件-------', ['newFile' => $newFile]);
                $filePath = 'uploads/agreement/' . date('Ymd') . '/' . $this->agreement['user_auth_name'] . '-' . $this->agreement['active_date'] . '-' . uniqid() . '-' . $pathinfo['basename']; //文件路径

                $res = QiniuStorage::disk('qiniu')->put($filePath, file_get_contents($newFile));
                Log::info('-------上传七牛云返回结果-------', ['qiniuyun-result' => json_encode($res)]);
                $agreement_file = '';
                if ($res) {
                    $obj = QiniuStorage::disk('qiniu')->downloadUrl($filePath);
                    $agreement_file = $obj->getUrl();
                    Log::info('-------获取七牛云的协议地址-------', ['qiniuyun-result' => json_encode($agreement_file)]);
                }
                $this->agreement->agreement_file = httpToHttps($agreement_file);
                $this->agreement->save();
                Log::info('----------生成协议调度任务结束了----------');
                // unlink(app()->basePath() . DIRECTORY_SEPARATOR . $path);
                // unlink($path);
                unlink($newFile);
            }
        } catch (\Exception $e) {
            Log::info('----------catch----------', ['exception' => json_encode($e)]);
            $this->failed($e);
        }
    }

    /**
     * 处理任务失败。
     *
     * @param  \Throwable  $exception
     * @return void
     */
    public function failed(\Throwable $exception)
    {
        Log::error('生成协议失败, msg: ' . $exception->getMessage(), [
            'project_id' => $this->project->id,
            'agreement_id' => $this->agreement->id
        ]);
        if ($this->attempts() < $this->tries) {
            return $this->release();
        } else {
            return $this->fail($exception);
        }
    }
}
